home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / xwindows / demos / xfract_1.z / xfract_1 / xfractint-1.06 / zoom.c < prev   
C/C++ Source or Header  |  1992-09-28  |  18KB  |  538 lines

  1. /*
  2.     zoom.c - routines for zoombox manipulation and for panning
  3.  
  4. */
  5.  
  6. #include <float.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "fractint.h"
  11. #include "prototyp.h"
  12.  
  13. /* screen dimensions here are (1.0,1.0) corresponding to (xdots-1,ydots-1) */
  14. extern double zbx,zby;           /* topleft of unrotated zoombox  */
  15. extern double zwidth,zdepth,zskew; /* zoombox size & shape        */
  16. extern int zrotate;           /* * 2.5 degree increments        */
  17. extern int boxcount,boxx[],boxy[]; /* co-ords of each zoombox pixel */
  18. extern int xdots,ydots,sxdots,sydots,sxoffs,syoffs;
  19. extern double dxsize,dysize;       /* xdots-1, ydots-1            */
  20. extern double xxmin,yymin,xxmax,yymax,xx3rd,yy3rd;
  21. extern double sxmin,symin,sxmax,symax,sx3rd,sy3rd;
  22. /* top      left    corner of screen is (xxmin,yymax) */
  23. /* bottom left    corner of screen is (xx3rd,yy3rd) */
  24. /* bottom right corner of screen is (xxmax,yymin) */
  25. extern double plotmx1,plotmx2,plotmy1,plotmy2;
  26.  
  27. extern int  calc_status;       /* status of calculations */
  28. extern int  fractype;           /* fractal type */
  29. extern char stdcalcmode;       /* '1', '2', 'g', 'b', or 't' */
  30. extern int  num_worklist;       /* resume worklist for standard engine */
  31. extern struct workliststuff worklist[MAXCALCWORK];
  32. extern char dstack[4096];       /* common temp, used for get_line/put_line */
  33. extern int  potflag;
  34. extern int  pot16bit;
  35. extern float finalaspectratio;
  36.  
  37. struct coords {
  38.     int x,y;
  39.     };
  40.  
  41. #define PIXELROUND 0.00001
  42.  
  43. static void _fastcall drawlines(struct coords, struct coords, int, int);
  44. static void _fastcall addbox(struct coords);
  45. static void _fastcall zmo_calc(double, double, double *, double *);
  46. static int  check_pan();
  47. static void fix_worklist();
  48. static void _fastcall move_row(int fromrow,int torow,int col);
  49.  
  50. void drawbox(int drawit)
  51. {   struct coords tl,bl,tr,br; /* dot addr of topleft, botleft, etc */
  52.     double tmpx,tmpy,dx,dy,rotcos,rotsin,ftemp1,ftemp2;
  53.     double fxwidth,fxskew,fydepth,fyskew,fxadj;
  54.  
  55.     if (zwidth==0) { /* no box to draw */
  56.     if (boxcount!=0) { /* remove the old box from display */
  57.         clearbox();   /* asm routine */
  58.         boxcount = 0; }
  59.     reset_zoom_corners();
  60.     return; }
  61.  
  62.     ftemp1 = PI*zrotate/72; /* convert to radians */
  63.     rotcos = cos(ftemp1);   /* sin & cos of rotation */
  64.     rotsin = sin(ftemp1);
  65.  
  66.     /* do some calcs just once here to reduce fp work a bit */
  67.     fxwidth = sxmax-sx3rd;
  68.     fxskew  = sx3rd-sxmin;
  69.     fydepth = sy3rd-symax;
  70.     fyskew  = symin-sy3rd;
  71.     fxadj   = zwidth*zskew;
  72.  
  73.     /* calc co-ords of topleft & botright corners of box */
  74.     tmpx = zwidth/-2+fxadj; /* from zoombox center as origin, on xdots scale */
  75.     tmpy = zdepth*finalaspectratio/2;
  76.     dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; /* delta x to rotate topleft */
  77.     dy = tmpy - (rotsin*tmpx + rotcos*tmpy); /* delta y to rotate topleft */
  78.     /* calc co-ords of topleft */
  79.     ftemp1 = zbx + dx + fxadj;
  80.     ftemp2 = zby + dy/finalaspectratio;
  81.     tl.x   = ftemp1*(dxsize+PIXELROUND); /* screen co-ords */
  82.     tl.y   = ftemp2*(dysize+PIXELROUND);
  83.     xxmin  = sxmin + ftemp1*fxwidth + ftemp2*fxskew; /* real co-ords */
  84.     yymax  = symax + ftemp2*fydepth + ftemp1*fyskew;
  85.     /* calc co-ords of bottom right */
  86.     ftemp1 = zbx + zwidth - dx - fxadj;
  87.     ftemp2 = zby - dy/finalaspectratio + zdepth;
  88.     br.x   = ftemp1*(dxsize+PIXELROUND);
  89.     br.y   = ftemp2*(dysize+PIXELROUND);
  90.     xxmax  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  91.     yymin  = symax + ftemp2*fydepth + ftemp1*fyskew;
  92.  
  93.     /* do the same for botleft & topright */
  94.     tmpx = zwidth/-2 - fxadj;
  95.     tmpy = 0.0-tmpy;
  96.     dx = (rotcos*tmpx - rotsin*tmpy) - tmpx;
  97.     dy = tmpy - (rotsin*tmpx + rotcos*tmpy);
  98.     ftemp1 = zbx + dx - fxadj;
  99.     ftemp2 = zby + dy/finalaspectratio + zdepth;
  100.     bl.x   = ftemp1*(dxsize+PIXELROUND);
  101.     bl.y   = ftemp2*(dysize+PIXELROUND);
  102.     xx3rd  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  103.     yy3rd  = symax + ftemp2*fydepth + ftemp1*fyskew;
  104.     ftemp1 = zbx + zwidth - dx + fxadj;
  105.     ftemp2 = zby - dy/finalaspectratio;
  106.     tr.x   = ftemp1*(dxsize+PIXELROUND);
  107.     tr.y   = ftemp2*(dysize+PIXELROUND);
  108.  
  109.     if (boxcount!=0) { /* remove the old box from display */
  110.     clearbox();   /* asm routine */
  111.     boxcount = 0; }
  112.  
  113.     if (drawit) { /* caller wants box drawn as well as co-ords calc'd */
  114. #ifndef XFRACT
  115.     /* build the list of zoom box pixels */
  116.     addbox(tl); addbox(tr);           /* corner pixels */
  117.     addbox(bl); addbox(br);
  118.     drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); /* top & bottom lines */
  119.     drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); /* left & right lines */
  120. #else
  121.         boxx[0] = tl.x + sxoffs;
  122.         boxy[0] = tl.y + syoffs;
  123.         boxx[1] = tr.x + sxoffs;
  124.         boxy[1] = tr.y + syoffs;
  125.         boxx[2] = br.x + sxoffs;
  126.         boxy[2] = br.y + syoffs;
  127.         boxx[3] = bl.x + sxoffs;
  128.         boxy[3] = bl.y + syoffs;
  129.         boxcount = 1;
  130. #endif
  131.     dispbox();                  /* asm routine to paint it */
  132.     }
  133.     }
  134.  
  135. static void _fastcall drawlines(struct coords fr, struct coords to,
  136.                 int dx, int dy)
  137. {   int xincr,yincr,ctr;
  138.     int altctr,altdec,altinc;
  139.     struct coords tmpp,line1,line2;
  140.  
  141.     if (abs(to.x-fr.x) > abs(to.y-fr.y)) { /* delta.x > delta.y */
  142.     if (fr.x>to.x) { /* swap so from.x is < to.x */
  143.         tmpp = fr; fr = to; to = tmpp; }
  144.     xincr = (to.x-fr.x)*4/sxdots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  145.     ctr = (to.x-fr.x-1)/xincr;
  146.     altdec = abs(to.y-fr.y)*xincr;
  147.     altinc = to.x-fr.x;
  148.     altctr = altinc/2;
  149.     yincr = (to.y>fr.y)?1:-1;
  150.     line2.x = (line1.x = fr.x) + dx;
  151.     line2.y = (line1.y = fr.y) + dy;
  152.     while (--ctr>=0) {
  153.         line1.x += xincr;
  154.         line2.x += xincr;
  155.         altctr -= altdec;
  156.         while (altctr<0) {
  157.         altctr    += altinc;
  158.         line1.y += yincr;
  159.         line2.y += yincr;
  160.         }
  161.         addbox(line1);
  162.         addbox(line2);
  163.         }
  164.     }
  165.  
  166.     else { /* delta.y > delta.x */
  167.     if (fr.y>to.y) { /* swap so from.y is < to.y */
  168.         tmpp = fr; fr = to; to = tmpp; }
  169.     yincr = (to.y-fr.y)*4/sydots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  170.     ctr = (to.y-fr.y-1)/yincr;
  171.     altdec = abs(to.x-fr.x)*yincr;
  172.     altinc = to.y-fr.y;
  173.     altctr = altinc/2;
  174.     xincr = (to.x>fr.x) ? 1 : -1;
  175.     line2.x = (line1.x = fr.x) + dx;
  176.     line2.y = (line1.y = fr.y) + dy;
  177.     while (--ctr>=0) {
  178.         line1.y += yincr;
  179.         line2.y += yincr;
  180.         altctr  -= altdec;
  181.         while (altctr<0) {
  182.         altctr    += altinc;
  183.         line1.x += xincr;
  184.         line2.x += xincr;
  185.         }
  186.         addbox(line1);
  187.         addbox(line2);
  188.         }
  189.     }
  190.     }
  191.  
  192. static void _fastcall addbox(struct coords point)
  193. {
  194.     point.x += sxoffs;
  195.     point.y += syoffs;
  196.     if (point.x >= 0 && point.x < sxdots && point.y >= 0 && point.y < sydots) {
  197.     boxx[boxcount] = point.x;
  198.     boxy[boxcount] = point.y;
  199.     ++boxcount;
  200.     }
  201.     }
  202.  
  203. void moveboxf(double dx, double dy)
  204. {   int align,row,col;
  205.     align = check_pan();
  206.     if (dx!=0.0) {
  207.     if ((zbx += dx) + zwidth/2 < 0)  /* center must stay onscreen */
  208.         zbx = zwidth/-2;
  209.     if (zbx + zwidth/2 > 1)
  210.         zbx = 1.0 - zwidth/2;
  211.     if (align != 0
  212.       && ((col = zbx*(dxsize+PIXELROUND)) & (align-1)) != 0) {
  213.         if (dx > 0) col += align;
  214.         col -= col & (align-1); /* adjust col to pass alignment */
  215.         zbx = (double)col/dxsize; }
  216.     }
  217.     if (dy!=0.0) {
  218.     if ((zby += dy) + zdepth/2 < 0)
  219.         zby = zdepth/-2;
  220.     if (zby + zdepth/2 > 1)
  221.         zby = 1.0 - zdepth/2;
  222.     if (align != 0
  223.       && ((row = zby*(dysize+PIXELROUND)) & (align-1)) != 0) {
  224.         if (dy > 0) row += align;
  225.         row -= row & (align-1);
  226.         zby = (double)row/dysize; }
  227.     }
  228.     }
  229.  
  230. static void _fastcall chgboxf(double dwidth, double ddepth)
  231. {
  232.     if (zwidth+dwidth > 1)
  233.     dwidth = 1.0-zwidth;
  234.     if (zwidth+dwidth < 0.05)
  235.     dwidth = 0.05-zwidth;
  236.     zwidth += dwidth;
  237.     if (zdepth+ddepth > 1)
  238.     ddepth = 1.0-zdepth;
  239.     if (zdepth+ddepth < 0.05)
  240.     ddepth = 0.05-zdepth;
  241.     zdepth += ddepth;
  242.     moveboxf(dwidth/-2,ddepth/-2); /* keep it centered & check limits */
  243.     }
  244.  
  245. void resizebox(int steps)
  246. {
  247.     double deltax,deltay;
  248.     if (zdepth*SCREENASPECT > zwidth) { /* box larger on y axis */
  249.     deltay = steps * 0.036 / SCREENASPECT;
  250.     deltax = zwidth * deltay / zdepth;
  251.     }
  252.     else {                /* box larger on x axis */
  253.     deltax = steps * 0.036;
  254.     deltay = zdepth * deltax / zwidth;
  255.     }
  256.     chgboxf(deltax,deltay);
  257.     }
  258.  
  259. void chgboxi(int dw, int dd)
  260. {   /* change size by pixels */
  261.     chgboxf( (double)dw/dxsize, (double)dd/